#ifndef CS_DISPATCHER_H
#define CS_DISPATCHER_H

#include <boost\bind.hpp>
#include <boost\function.hpp>
#include <boost\assign.hpp>
#include <map>
#include <utils\logger.h>

#include "messages_id.h"
#include "message_proto_typedef.h"
#include "registry.h"
#include "message.h"


namespace cs
{
	class dispatcher
	{
	public:
		dispatcher(registry::session_ptr session);
		void dispatch(message_handle msg);
	private:
		typedef boost::function<void(message_handle)> handle_t;
		typedef std::map<address, handle_t> dispatching_map_t;

		registry::session_ptr session_;
		dispatching_map_t dispatching_map;

		address session_addr;
		utils::logger logger;

		void generate_dispatching_map();
		void send_session_address();
		template<typename MESSAGE>
		void handle(message_handle msg);
		void forward(message_handle msg);
		void handle(register_service_req_proto pmsg);
		void handle(subscribe_service_req_proto pmsg);
		void notif_subscribers(const std::string& service_name);
		service_address_proto prepare_service_addr_proto(const address& addr,const std::string& name);
	};

	template<typename MESSAGE>
	void dispatcher::handle(message_handle msg)
	{
		MESSAGE pmsg(msg->get());
		if (pmsg.is_valid()) {
			handle(pmsg);
		}
	}
	
} //end namespace cs
#endif /* CS_DISPATCHER_H */